home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / msysjour / ms / s12410 / pipe.c < prev    next >
C/C++ Source or Header  |  1989-09-20  |  5KB  |  180 lines

  1. /* pipe.c RHS 5/2/89
  2.  *
  3.  * pipe example:
  4.  *
  5.  * this program will reroute the stdout of a child process to the pipe,
  6.  * then it will print the child's output to the upper portion of the screen
  7.  * while you can type into the lower portion of the screen
  8.  *
  9.  * To run:
  10.  *
  11.  *        PIPE <child program name> [child program arguments]
  12.  *
  13.  */
  14.  
  15. #define INCL_DOS
  16. #define INCL_KBD
  17. #define INCL_VIO
  18. #define INCL_ERRORS
  19.  
  20. #include<os2.h>
  21. #include<mt\stdio.h>
  22. #include<mt\process.h>
  23. #include<mt\string.h>
  24.  
  25. #define     PIPESIZE     80
  26. #define    STDIN            0
  27. #define    STDOUT        1
  28. #define    FAILBUFLEN    128
  29. #define    ENV            0L
  30. #define    THREADSTACK    800
  31.  
  32. char readbuf[PIPESIZE+5];
  33. HFILE readhandle, writehandle, newSTDOUT = STDOUT;
  34. USHORT cell = 0x1f20;
  35. char readchild_stack[THREADSTACK];
  36.  
  37.  
  38. void error_exit(USHORT err, char *msg);
  39. PID Os2GetPid(void);
  40. void main(int argc, char **argv);
  41. void readchild(void);
  42.  
  43. void main(int argc, char **argv)
  44.     {
  45.     USHORT retval, cell2 = 0x1fc4, i;
  46.     STRINGINBUF stringinbuf;
  47.     char failbuf[FAILBUFLEN];
  48.     RESULTCODES resultcodes;
  49.     char keybuf[PIPESIZE], *p;
  50.     PID pid,pidasync;
  51.  
  52.     if(argc < 2)                                            /* must have one argument    */
  53.         error_exit(0,"main");
  54.  
  55.                                                                 /* create pipe                    */
  56.     if(retval = DosMakePipe( &readhandle, &writehandle, PIPESIZE))
  57.         error_exit(retval,"DosMakePipe");
  58.  
  59.     DosClose(STDOUT);                                        /* close stdout                */
  60.  
  61.                                                         /* pipe write handle now stdout    */
  62.     if(retval = DosDupHandle(writehandle,&newSTDOUT))
  63.         error_exit(retval,"DosDupHandle");
  64.  
  65.                                                                 /* clear the screen            */
  66.     VioScrollUp(0,0,0xffff,0xffff,0xffff,(PBYTE)&cell,0);
  67.     VioWrtNCell((PBYTE)&cell2,80,11,0,0);            /* draw line to split screen*/
  68.  
  69.     memset(readbuf,0,sizeof(readbuf));                /* clear buffer                */
  70.     strcpy(readbuf,argv[1]);                            /* add program name            */
  71.     if(!(strstr(strupr(readbuf),".EXE")))            /* tack on .EXE                */
  72.         strcat(readbuf,".EXE");
  73.  
  74.     p = (&readbuf[strlen(readbuf)]+1);
  75.     for( i = 2; i < argc; i++)                            /* add program arguments    */
  76.         {
  77.         strcat(p,argv[i]);
  78.         strcat(p," ");
  79.         }
  80.                                                                 /* run the child program    */
  81.     if(retval = DosExecPgm(failbuf,FAILBUFLEN,EXEC_ASYNC,readbuf,ENV,
  82.             &resultcodes, readbuf))
  83.         error_exit(retval,"DosExecPgm");
  84.     pidasync = resultcodes.codeTerminate;
  85.  
  86.                                                                 /* start pipe read thread    */
  87.     if(_beginthread(readchild,readchild_stack,THREADSTACK,NULL) == -1)
  88.         error_exit(-1,"_beginthread");
  89.  
  90.     while(TRUE)
  91.         {
  92.         stringinbuf.cb = sizeof(keybuf)-1;
  93.  
  94.                                                                 /* await operator input        */
  95.         if(retval = KbdStringIn(keybuf,&stringinbuf,IO_WAIT,0))
  96.             error_exit(retval,"KbdStringIn");
  97.  
  98.         keybuf[stringinbuf.cchIn] = '\0';
  99.                                                                 /* scroll screen up            */
  100.         VioScrollUp(12,0,23,0xffff,1,(PBYTE)&cell,0);
  101.                                                                 /* write command                */
  102.         VioWrtCharStr(keybuf,strlen(keybuf),23,0,0);
  103.                                                                 /* clear prompt line            */
  104.         VioWrtNCell((PBYTE)&cell,80,24,0,0);
  105.         if(!strcmp(strupr(keybuf),"QUIT"))            /* if QUIT command, get out*/
  106.             break;
  107.         }
  108.                                                                 /* see if child finished    */
  109.     if(retval = DosCwait(DCWA_PROCESSTREE,DCWW_NOWAIT,&resultcodes,&pid,
  110.             resultcodes.codeTerminate))
  111.         {
  112.         if(retval == ERROR_CHILD_NOT_COMPLETE)        /* if not, kill it            */
  113.             {
  114.             if(retval = DosKillProcess(DKP_PROCESSTREE,pidasync))
  115.                 error_exit(retval,"DosKillProcess");
  116.             }
  117.         else if(retval != ERROR_WAIT_NO_CHILDREN)
  118.             error_exit(retval,"DosCwait");
  119.         }
  120.  
  121.     DosExit(EXIT_PROCESS,0);                            /* get out                        */
  122.     }
  123.  
  124.  
  125. void readchild(void)        /* this thread reads the pipe, and prints the lines*/
  126.     {
  127.     USHORT retval,bytesread,i, lines;
  128.     char *p = readbuf;
  129.  
  130.     while(TRUE)
  131.         {                                                        /* read the pipe                */
  132.         if(retval = DosRead(readhandle,p,PIPESIZE-(p-readbuf),&bytesread))
  133.             error_exit(retval,"DosRead");
  134.         bytesread += (p-readbuf);
  135.                         
  136.         for(i = lines =0; i < bytesread; i++)        /* remove CRs and LFs        */
  137.             {
  138.             if(readbuf[i] == '\n')
  139.                 lines++;
  140.             if(readbuf[i] == '\r' || readbuf[i] == '\n')
  141.                 readbuf[i] = '\0';
  142.             }
  143.                                                                 /* print each line found    */
  144.         for(p = readbuf, i = 0; i < bytesread && lines; lines--)
  145.             {
  146.             VioScrollUp(0,0,10,0xffff,1,(PBYTE)&cell,0);
  147.             VioWrtCharStr(p,strlen(p),10,0,0);
  148.             i += strlen(p);
  149.             p += strlen(p);
  150.             for( ; !(*p) && i < bytesread; i++, p++);
  151.             DosSleep(1L);
  152.             }
  153.  
  154.         if(*p && !lines && i < bytesread)            /* if anything leftover        */
  155.             {
  156.             memmove(readbuf,p,bytesread-i);            /* move it up                    */
  157.             p = &readbuf[bytesread-i];
  158.             }
  159.         else
  160.             p = readbuf;
  161.         }
  162.     }
  163.  
  164. PID Os2GetPid(void)                                        /* returns process id        */
  165.     {
  166.     PIDINFO pidinfo;
  167.  
  168.     DosGetPID(&pidinfo);                                    /* get process id                */
  169.     return pidinfo.pid;                                    /* return it                    */
  170.     }
  171.  
  172. void error_exit(USHORT err, char *msg)
  173.     {
  174.     char buf[100];
  175.  
  176.     sprintf(buf,"Error %u returned from %s\r\n",err,msg);
  177.     VioWrtTTY(buf,strlen(buf),0);
  178.     DosExit(EXIT_PROCESS,0);
  179.     }
  180.